#include <iostream>
#include<unistd.h>
#include<cstring>
#include<string.h>
#include<vector>
#include<semaphore.h>
#include<pthread.h>
using  namespace std;
#define SIZE 5
template<class T>
class RingQueue
{
    public:
    RingQueue()
    :_capacity(SIZE),
    _ring(SIZE)
    {
        pthread_mutex_init(&_pro_mutex,nullptr);
        pthread_mutex_init(&_cust_mutex,nullptr);
        sem_init(&_pro_space,0,_capacity);
        sem_init(&_cust_data,0,0);
    }   

    void push(const T& data)
    {
        sem_wait(&_pro_space);
        pthread_mutex_lock(&_pro_mutex);
        _ring[_pro_pos++]=data;
        _pro_pos%=_capacity;
        pthread_mutex_unlock(&_pro_mutex);
        sem_post(&_cust_data);
    }


    void pop(T& out)
    {
        sem_wait(&_cust_data);
        pthread_mutex_lock(&_cust_mutex);
        out=_ring[_cust_pos++];
        _cust_pos%=_capacity;
        pthread_mutex_unlock(&_cust_mutex);
        sem_post(&_pro_space);
    }


    private:
    vector<T> _ring;
    pthread_mutex_t _pro_mutex;
    pthread_mutex_t _cust_mutex;
    sem_t _pro_space;
    sem_t _cust_data;
    int _capacity;
    int _pro_pos=0;
    int _cust_pos=0;
};